const express = require('express');
const { ExceptionHandler } = require('../consistency');
const { PerformanceMonitor } = require('../performance');

class SearchService {
    constructor() {
        this.app = express();
        this.port = process.env.SEARCH_SERVICE_PORT || 3004;
        this.exceptionHandler = new ExceptionHandler();
        this.performanceMonitor = new PerformanceMonitor();
        
        // 搜索索引
        this.searchIndex = new Map();
        this.synonyms = new Map();
        this.searchHistory = [];
        
        this.setupMiddleware();
        this.setupRoutes();
        this.initializeSynonyms();
    }

    setupMiddleware() {
        this.app.use(express.json({ limit: '1mb' }));
        this.app.use(express.urlencoded({ extended: true }));
        
        // 性能监控
        this.app.use((req, res, next) => {
            const startTime = Date.now();
            res.on('finish', () => {
                const responseTime = Date.now() - startTime;
                this.performanceMonitor.recordRequest(req.path, req.method, responseTime, res.statusCode);
            });
            next();
        });
    }

    setupRoutes() {
        // 健康检查
        this.app.get('/health', (req, res) => {
            res.json({
                service: 'search-service',
                status: 'healthy',
                indexSize: this.searchIndex.size,
                searchHistoryCount: this.searchHistory.length,
                timestamp: Date.now()
            });
        });

        // 全文搜索
        this.app.get('/api/search', this.fullTextSearch.bind(this));
        
        // 高级搜索
        this.app.post('/api/search/advanced', this.advancedSearch.bind(this));
        
        // 搜索建议
        this.app.get('/api/search/suggest', this.searchSuggestions.bind(this));
        
        // 搜索历史
        this.app.get('/api/search/history', this.getSearchHistory.bind(this));
        
        // 索引管理
        this.app.post('/api/search/index', this.updateIndex.bind(this));
        
        // 搜索统计
        this.app.get('/api/search/stats', this.getSearchStats.bind(this));
    }

    // 初始化同义词库
    initializeSynonyms() {
        this.synonyms.set('前端', ['前端开发', 'web前端', '前端技术']);
        this.synonyms.set('后端', ['后端开发', '服务器端', '后端技术']);
        this.synonyms.set('数据库', ['数据存储', 'DB', '数据库系统']);
        this.synonyms.set('JavaScript', ['JS', 'ECMAScript']);
        this.synonyms.set('Node.js', ['Node', 'NodeJS']);
    }

    // 全文搜索
    fullTextSearch(req, res) {
        try {
            const { 
                q, 
                type = 'all', 
                page = 1, 
                limit = 10,
                sortBy = 'relevance',
                filters = {}
            } = req.query;
            
            if (!q) {
                return res.status(400).json({
                    success: false,
                    message: '搜索关键词不能为空'
                });
            }
            
            // 记录搜索历史
            this.recordSearchHistory(q, req.ip);
            
            // 分词和扩展
            const searchTerms = this.tokenizeQuery(q);
            const expandedTerms = this.expandSynonyms(searchTerms);
            
            // 执行搜索
            const searchResults = this.executeSearch(expandedTerms, filters, type);
            
            // 排序
            const sortedResults = this.sortResults(searchResults, sortBy);
            
            // 分页
            const pageNum = parseInt(page);
            const limitNum = parseInt(limit);
            const startIndex = (pageNum - 1) * limitNum;
            const endIndex = startIndex + limitNum;
            const paginatedResults = sortedResults.slice(startIndex, endIndex);
            
            res.json({
                success: true,
                data: {
                    results: paginatedResults,
                    searchInfo: {
                        query: q,
                        originalTerms: searchTerms,
                        expandedTerms: expandedTerms,
                        totalResults: sortedResults.length,
                        searchTime: Date.now()
                    },
                    pagination: {
                        page: pageNum,
                        limit: limitNum,
                        total: sortedResults.length,
                        totalPages: Math.ceil(sortedResults.length / limitNum)
                    }
                }
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/search' });
            res.status(500).json({
                success: false,
                message: '搜索失败'
            });
        }
    }

    // 高级搜索
    advancedSearch(req, res) {
        try {
            const { 
                query,
                filters = {},
                sortBy = 'relevance',
                page = 1,
                limit = 10
            } = req.body;
            
            if (!query) {
                return res.status(400).json({
                    success: false,
                    message: '搜索条件不能为空'
                });
            }
            
            // 记录搜索历史
            this.recordSearchHistory(JSON.stringify(query), req.ip);
            
            // 构建搜索条件
            const searchConditions = this.buildSearchConditions(query);
            
            // 执行搜索
            const searchResults = this.executeAdvancedSearch(searchConditions, filters);
            
            // 排序
            const sortedResults = this.sortResults(searchResults, sortBy);
            
            // 分页
            const pageNum = parseInt(page);
            const limitNum = parseInt(limit);
            const startIndex = (pageNum - 1) * limitNum;
            const endIndex = startIndex + limitNum;
            const paginatedResults = sortedResults.slice(startIndex, endIndex);
            
            res.json({
                success: true,
                data: {
                    results: paginatedResults,
                    searchInfo: {
                        query: query,
                        conditions: searchConditions,
                        totalResults: sortedResults.length
                    },
                    pagination: {
                        page: pageNum,
                        limit: limitNum,
                        total: sortedResults.length,
                        totalPages: Math.ceil(sortedResults.length / limitNum)
                    }
                }
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/search/advanced' });
            res.status(500).json({
                success: false,
                message: '高级搜索失败'
            });
        }
    }

    // 搜索建议
    searchSuggestions(req, res) {
        try {
            const { q, limit = 5 } = req.query;
            
            if (!q) {
                return res.json({
                    success: true,
                    data: []
                });
            }
            
            const suggestions = this.generateSuggestions(q, parseInt(limit));
            
            res.json({
                success: true,
                data: suggestions
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/search/suggest' });
            res.status(500).json({
                success: false,
                message: '获取搜索建议失败'
            });
        }
    }

    // 获取搜索历史
    getSearchHistory(req, res) {
        try {
            const { limit = 10 } = req.query;
            const userHistory = this.searchHistory
                .filter(record => record.ip === req.ip)
                .slice(0, parseInt(limit))
                .map(record => ({
                    query: record.query,
                    timestamp: record.timestamp,
                    resultCount: record.resultCount
                }));
            
            res.json({
                success: true,
                data: userHistory
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/search/history' });
            res.status(500).json({
                success: false,
                message: '获取搜索历史失败'
            });
        }
    }

    // 更新索引
    updateIndex(req, res) {
        try {
            const { operation, data } = req.body;
            
            switch (operation) {
                case 'add':
                    this.addToIndex(data);
                    break;
                case 'remove':
                    this.removeFromIndex(data);
                    break;
                case 'update':
                    this.updateInIndex(data);
                    break;
                default:
                    return res.status(400).json({
                        success: false,
                        message: '不支持的操作类型'
                    });
            }
            
            res.json({
                success: true,
                message: '索引更新成功'
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/search/index' });
            res.status(500).json({
                success: false,
                message: '索引更新失败'
            });
        }
    }

    // 获取搜索统计
    getSearchStats(req, res) {
        try {
            const stats = {
                totalSearches: this.searchHistory.length,
                uniqueQueries: new Set(this.searchHistory.map(r => r.query)).size,
                popularQueries: this.getPopularQueries(10),
                searchTrends: this.getSearchTrends(),
                indexStats: {
                    totalTerms: this.searchIndex.size,
                    averageResultsPerTerm: this.calculateAverageResults()
                }
            };
            
            res.json({
                success: true,
                data: stats
            });
            
        } catch (error) {
            this.exceptionHandler.logException(error, { endpoint: '/api/search/stats' });
            res.status(500).json({
                success: false,
                message: '获取搜索统计失败'
            });
        }
    }

    // 分词处理
    tokenizeQuery(query) {
        return query
            .toLowerCase()
            .replace(/[^\w\u4e00-\u9fa5]/g, ' ')
            .split(/\s+/)
            .filter(term => term.length > 0);
    }

    // 扩展同义词
    expandSynonyms(terms) {
        const expanded = new Set(terms);
        
        terms.forEach(term => {
            if (this.synonyms.has(term)) {
                this.synonyms.get(term).forEach(synonym => {
                    expanded.add(synonym);
                });
            }
        });
        
        return Array.from(expanded);
    }

    // 执行搜索
    executeSearch(terms, filters, type) {
        // 简化版搜索实现
        // 实际项目中可以使用Elasticsearch等专业搜索引擎
        const results = [];
        
        terms.forEach(term => {
            if (this.searchIndex.has(term)) {
                const documents = this.searchIndex.get(term);
                documents.forEach(doc => {
                    // 应用过滤器
                    if (this.applyFilters(doc, filters, type)) {
                        results.push({
                            ...doc,
                            relevance: this.calculateRelevance(doc, terms)
                        });
                    }
                });
            }
        });
        
        return results;
    }

    // 构建搜索条件
    buildSearchConditions(query) {
        // 支持AND、OR、NOT等逻辑操作
        return {
            must: query.must || [],
            should: query.should || [],
            mustNot: query.mustNot || [],
            range: query.range || {}
        };
    }

    // 执行高级搜索
    executeAdvancedSearch(conditions, filters) {
        // 简化版高级搜索实现
        const results = [];
        
        // 这里实现复杂的搜索逻辑
        // ...
        
        return results;
    }

    // 应用过滤器
    applyFilters(document, filters, type) {
        if (type !== 'all' && document.type !== type) {
            return false;
        }
        
        // 应用其他过滤器
        for (const [key, value] of Object.entries(filters)) {
            if (document[key] !== value) {
                return false;
            }
        }
        
        return true;
    }

    // 计算相关性
    calculateRelevance(document, terms) {
        let score = 0;
        
        terms.forEach(term => {
            if (document.title && document.title.toLowerCase().includes(term)) {
                score += 3;
            }
            if (document.content && document.content.toLowerCase().includes(term)) {
                score += 1;
            }
            if (document.keywords && document.keywords.includes(term)) {
                score += 2;
            }
        });
        
        return score;
    }

    // 排序结果
    sortResults(results, sortBy) {
        return results.sort((a, b) => {
            switch (sortBy) {
                case 'relevance':
                    return b.relevance - a.relevance;
                case 'date':
                    return new Date(b.date) - new Date(a.date);
                case 'title':
                    return a.title.localeCompare(b.title);
                default:
                    return b.relevance - a.relevance;
            }
        });
    }

    // 记录搜索历史
    recordSearchHistory(query, ip) {
        this.searchHistory.push({
            query,
            ip,
            timestamp: Date.now(),
            resultCount: 0 // 实际搜索后更新
        });
        
        // 限制历史记录大小
        if (this.searchHistory.length > 1000) {
            this.searchHistory.shift();
        }
    }

    // 生成搜索建议
    generateSuggestions(query, limit) {
        const suggestions = [];
        const terms = this.tokenizeQuery(query);
        
        terms.forEach(term => {
            // 基于搜索索引生成建议
            for (const indexedTerm of this.searchIndex.keys()) {
                if (indexedTerm.startsWith(term) && suggestions.length < limit) {
                    suggestions.push(indexedTerm);
                }
            }
        });
        
        return [...new Set(suggestions)].slice(0, limit);
    }

    // 添加到索引
    addToIndex(data) {
        const terms = this.tokenizeQuery(data.title + ' ' + data.content);
        
        terms.forEach(term => {
            if (!this.searchIndex.has(term)) {
                this.searchIndex.set(term, new Set());
            }
            this.searchIndex.get(term).add(data);
        });
    }

    // 从索引中移除
    removeFromIndex(data) {
        for (const [term, documents] of this.searchIndex.entries()) {
            documents.delete(data);
            if (documents.size === 0) {
                this.searchIndex.delete(term);
            }
        }
    }

    // 更新索引
    updateInIndex(data) {
        this.removeFromIndex(data);
        this.addToIndex(data);
    }

    // 获取热门查询
    getPopularQueries(limit) {
        const queryCounts = new Map();
        
        this.searchHistory.forEach(record => {
            queryCounts.set(record.query, (queryCounts.get(record.query) || 0) + 1);
        });
        
        return Array.from(queryCounts.entries())
            .sort((a, b) => b[1] - a[1])
            .slice(0, limit)
            .map(([query, count]) => ({ query, count }));
    }

    // 获取搜索趋势
    getSearchTrends() {
        const trends = {};
        const oneWeekAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
        
        this.searchHistory
            .filter(record => record.timestamp > oneWeekAgo)
            .forEach(record => {
                const date = new Date(record.timestamp).toISOString().split('T')[0];
                trends[date] = (trends[date] || 0) + 1;
            });
        
        return trends;
    }

    // 计算平均结果数
    calculateAverageResults() {
        if (this.searchIndex.size === 0) return 0;
        
        let totalResults = 0;
        for (const documents of this.searchIndex.values()) {
            totalResults += documents.size;
        }
        
        return totalResults / this.searchIndex.size;
    }

    // 启动服务
    start() {
        return this.app.listen(this.port, () => {
            console.log(`🔍 Search Service running on port ${this.port}`);
            console.log(`📊 Health check: http://localhost:${this.port}/health`);
            console.log(`📚 Search index ready with ${this.searchIndex.size} terms`);
        });
    }
}

// 如果直接运行此文件，启动服务
if (require.main === module) {
    const searchService = new SearchService();
    searchService.start();
}

module.exports = SearchService;